home *** CD-ROM | disk | FTP | other *** search
/ Your Choice 3 / Your Choice Software Collection 3.iso / prgmming / swag05 / drives.swg < prev    next >
Text File  |  1994-09-22  |  20KB  |  1 lines

  1. SWAGOLX.EXE (c) 1993 GDSOFT  ALL RIGHTS RESERVED 00002                                                                           1      05-25-9408:14ALL                      MIGUEL MARTINEZ          File Allocation Unit SizeSWAG9405            10     ╣   {π ▒ Anybody know a realitively easy way to determine the file allocationπ ▒ unit size offa hard/floppy drive??  Pascal source would be prefered overπ ▒ pascal assembly as I know next to nothing about assembly.π}π{───────────────────────────────────────────────────────────────}πFunction GetUA(Drive: Byte:LongInt; {0=Default, 1=A, 2=B,..etc .}πVar regs:Registers;πBeginπ  regs.ah:=$1C;   { Int 21h, Function 1Ch: Get drive data       }π                  { * Parameters:                               }π  regs.dl:=Drive; {     DL = Drive code                         }π  intr($21,regs); { Call function.                              }π                  { * Returns:                                  }π                  {     AL = Sectors per cluster                }π                  {     DS:DX = Segment:Offset of ID byte       }π                  {     CX = Physical sector length (bytes)     }π                  {     DX = Number of clusters of default unit }π  GetUA:=regs.al*regs.cx; { Returns SPC*SL                      }πEnd;π                                                                                                                    2      05-25-9408:27ALL                      LEE ARONER               Default Boot Drive       SWAG9405            145    ╣   {$A+,B-,D+,E-,F-,G-,I+,L-,N-,O-,R-,S-,T-,V-,X+}π{$M 3072,0,0}ππ(*  A program to test some interesting behaviour of Int 21h,π    function 44h subfunction 08h.....the MicroSoft documentation Iπ    have seen indicates only that this returns an error if the flagsπ    register is set. however, it seems that it also identifies theπ    default bootable logical drive, whether the machine was bootedπ    from a floppy, and discriminates between Ram drives and normalπ    HDrives.....& more! Would appreciate your assistance inπ    running this test and returning this information to me by mail.π    The results will be published in the FIDO Pascal echo.ππ    **************** WARNING  *****************π    Although this program has run completely safely on all machinesπ    tested by me, you should shut down or save all critical processesπ    before running this test.ππ                    L.R.A.  5/6/94                          *)ππProgram TestDisk;ππUses   Dos;ππConstπ  TapeDrive    = $01;π  CdRom        = $02;π  Floppy       = $03;    (* Old 8 inch & ALL Floppies *)π  Floppy360    = $04;    (* Also 320K Floppy *)π  Floppy720    = $05;π  Floppy12     = $06;π  Floppy14     = $07;π  Floppy28     = $08;π  Floptical    = $09;π  Bernoulli    = $0a;π  RamDrive     = $0b;π  HardDrive    = $0c;π  BootHrdDrive = $0d;   (* Default HARD-Disk BootDrive !!! *)ππ  DriveTypes : array[0..13] of string[12] =π               ('ERROR !',      'TapeDrive',    'CdRom',π                'Floppy',       '360K Floppy',  '720K Floppy',π                '1.2M Floppy',  '1.44M Floppy', '2.88M Floppy',π                'Floptical',    'Bernoulli',    'RamDrive',π                'HardDrive',    'BootHrdDrive');ππVarπ  i           : byte;π  bits        : string[16];π  buff        : array [0..2047] of byte;π  drive       : char;π  Dtype       : byte;π  f           : text;π  y,m,d,dow   : word;π  lastdrive   : byte;π  regs        : registers;π  version     : word;ππ(*------------------------------------------------------*)πFunction BinStr(num:word;bits:byte):string; assembler;πASMπ      PUSHFπ      LES  DI, @Resultπ      XOR  CH, CHπ      MOV  CL, bitsπ      MOV  ES:[DI], CLπ      JCXZ @@3π      ADD  DI, CXπ      MOV  BX, numπ      STDπ@@1:  MOV  AL, BLπ      AND  AL, $01π      OR   AL, $30π      STOSBπ      SHR  BX, 1π      LOOP @@1π@@3:  POPFπEnd;ππ(*------------------------------------------------------*)πFunction DosVersion : word;πBeginπ  with regs doπ    beginπ      ax := $3000;π      Intr($21,regs);π      DosVersion := (word(al)*100)+word(ah);π   end;πEnd;ππ(*---------------------------------------------------------*)π   (* Uses Undocumented function 52h to return actual logicalπ      lastdrive even under Novell and even if LastDrive is notπ      used in Config.Sys. Must be DOS 3.1 or higher !!π      Return is 1 based ie: A=1, B=2, C=3, etc. !!!!ππ      Note: this will always return 5 if lastdrive is notπ      specified in config.sys, even if less then 5 drives !                            *)ππFunction GetLastDrive(Var Drives:byte):boolean;πBeginπ  With regs doπ    beginπ      ah := $52;       (* Return pointer to List of Lists *)π      es := 0;π      bx := 0;π      Intr($21,regs);π  (* This offset is ONLY valid for DOS 3.1 and above !! *)π      Drives := Mem[es:bx+$21];π      GetLastDrive := (Drives <> $FF)π              AND ((es <> 0) AND (bx <> 0));π    end;πEnd;ππ(*-----------------------------------------------------------*)π(* Switches to requested drive and then checks for error -π   Be sure to call this with Drive UpCased !! - Should work OKπ   with networks ???????                                     *)ππFunction DriveValid(drive: char): boolean; assembler;πasmπ    mov   ah, 19h     { Select DOS sub function 19h }π    int   21h         { Call DOS for current disk drive }π    mov   bl, al      { Save drive code in bl }π    mov   al, Drive   { Assign requested drive to al }π    sub   al, 'A'     { Adjust so A:=0, B:=1, etc. }π    mov   dl, al      { Save adjusted result in dl }π    mov   ah, 0eh     { Select DOS sub function 0eh }π    int   21h         { Call DOS to set default drive }π    mov   ah, 19h     { Select DOS sub function 19h }π    int   21h         { Get current drive again }π    mov   cx, 0       { Preset result to False }π    cmp   al, dl      { Check if drives match }π    jne   @@1         { Jump if not--drive not valid }π    mov   cx, 1       { Preset result to True }π@@1:π    mov   dl, bl      { Restore original default drive }π    mov   ah, 0eh     { Select DOS sub function 0eh }π    int   21h         { Call DOS to set default drive }π    xchg  ax, cx      { Return function result in ax }πEnd;π(*-----------------------------------------------------*)π   (* Be sure to call this with drive UpCased ! *)ππFunction IsCDRom(drive : char) : boolean;πBeginπ   with regs doπ     beginπ       ax := $150b;π       bx := $0000;π       cx := word(ord(drive)-65);π       Intr($2f,regs);π    (* If MSCDEX is loaded, bx will be $adad ! *)π       IsCDRom := (ax <> 0) AND (bx = $adad);π    end;πEnd;ππ(*-----------------------------------------------------*)π   (* Returns false if drive is local - untested !!! *)ππFunction DriveIsRemote(drive : char):boolean;πBeginπ  with regs doπ    beginπ      ah := $44;π      al := $09;π      bl := ord(drive)-64;π      Intr($21,regs);π      DriveIsRemote := ((dx AND $1000) <> 0) AND (fCarry = 0);π (* Can further check if drive is substituted withπ                  dx AND $8000 = $8000 if so *)π    end;πEnd;ππ(*------------------------------------------------------*)π       (* Be sure that Drive is UPCASED !π    Returns FALSE on Anything that is NOT a HardDisk,π    including RamDisks, CdRom, etc.                    *)ππFunction IsHardDisk(drive:char):boolean;πBeginπ  with regs DOπ    beginπ      ah := $44;π      al := $08;π      bl := ord(drive)-64;π      Intr($21, regs);π      IsHardDisk := (flags AND fCarry <> fCarry)π           AND (NOT (ax in [$0,$0f]));π     (* ax = $0 for removable, $0f on invalid drive spec ! *)π    end;πEnd;ππ(*------------------------------------------------------------------*)π   (* CAUTION !!!!! THIS FUNCTION IS EXPERIMENTAL !!!!!!!!!  *)ππ (* Be sure that drive is UPCASED ! - This function goes to DOSπ    internal structures to get params for floppy type drives.π    (Including Bernoulli). Because it tells DOS to rebuild theπ    BPB (Bios Parameter Block) for drives with removable media,π    the Media Descriptor byte will always return the bootπ    paramaters for the drive, ie: a 1.44M floppy will alwaysπ    return 1.44M, regardless of the size disk that is currentlyπ    actually in the drive !!ππ    A return of BootHrdDrive indicates ONLY that this is theπ    HardDrive with the DOS boot partition on it. It DOES NOTπ    indicate that the machine was booted from that drive !!!ππ    Dos version is MINIMUM of 3.1 !! - Check FIRST !!ππ    Because it does NOT read the drive, this puppy is FAST !!ππ    Returns these Constant types :π                    ERROR !       = $00;π                    TapeDrive     = $01π                    CdRom         = $02;πCheck against this- Floppy        = $03; -to get All floppys !!π                    Floppy360     = $04;π                    Floppy720     = $05;π                    Floppy12      = $06;π                    Floppy14      = $07;π                    Floppy28      = $08;π                    Floptical     = $09;π                    Bernoulli     = $0a;π                          RamDrive      = $0b;π                    HardDrive     = $0c;π                    BootHrdDrive  = $0d;     *)ππFunction DriveType(Var f:text;drive:char):byte;πTypeπ   PtrDpbPtr = ^DpbPtr;π   DpbPtr    = ^DPB;ππ   DPB  =  record           (* Drive Parameter Block *)π     DN   : byte;      (* 0=A etc Can compare this for Subst drive *)π     DDU  : byte;      (* Device Driver Unit Number *)π     BPS  : word;      (* Bytes Per Sector *)π     SPC  : byte;      (* Sectors Per Cluster *)π     CSC  : byte;      (* Cluster Shift Count *)π     BS   : word;      (* Boot Sectors *)π     Fats : byte;      (* Number of fats *)π     RDE  : word;      (* Max Root Dir entries *)π     FDS  : word;      (* First Data Sector *)π     HPC  : word;      (* Highest Possible Cluster # *)π    (* Case Variant *)π     Case byte ofπ        (* DOS < 4.0 OR OS2 *)π       0 : (SpfOld   : byte;   (* Sectors per fat *)π            JunkOld  : array[16..22] of byte;π            MdaOld   : byte;   (* Media Descriptor byte *)π            DummyOld : byte;π            NextOld  : DpbPtr); (* Pointer to next record *)π       (* DOS >= 4.0 *)π       1 :(SpfNew    : word;π           JunkNew   : array[17..23] of byte;π           MdaNew    : byte;π           DummyNew  : byte;π           NextNew   : DpbPtr);π       end;πVarπ  dnum,i,π  num     : byte;π  CurrDpB : DpbPtr;π  MDA     : byte;π  SPF     : word;π  params  : array[0..31] of byte;π  UseNew  : boolean;ππBeginπ  DriveType := 0;              (* Assume failure *)π  dnum := ord(drive)-64;       (* 'A'=1, 'B'=2 etc. *)π  with regs doπ    beginπ      ah := $44;π      al := $08;π      bl := dnum;π      Intr($21, regs);π      if ax = $0f then exit;   (* Invalid drive ! *)π (* Here's where we try the undocumented return params ! *)π      num := (ax+(flags AND fCarry)+(flags AND fParity));ππ   {  if (ax = 0) then        - Diversion for test purposes !π        begin  }π          (* OS2 will return > 10 *)π          UseNew := Lo(DosVersion) in [4..9];ππ    (* Get Ptr to List of Lists *)π          ah := $52;π          es := 0;π          bx := 0;π          Intr($21,regs);π          if (es = 0) OR (bx = 0) then exit;  (* Error ! *)ππ       (* Pointer to list - 0h is pointer to 1st DPB *)π          CurrDpb := PtrDpbPtr(Ptr(es,bx))^;π    (* Walk the chain of DPB's to our drive: 0='A' etc. *)π (* Possible that drive is SUBSTed, so index from dnum instead of DN ! *)π    (* Don't index on 'A', cause it's already there ! *)π          for i := 2 to dnum doπ            beginπ       (* Offset set to $ffff on last in chain *)π              if (ofs(CurrDpb^) <> $ffff) thenπ                beginπ                  if UseNew then CurrDpb := CurrDpb^.NextNewπ                  else CurrDpb := CurrDpb^.NextOld;π                endπ     (* Hit end of chain before got to our drive ! *)π              else exit;π            end;   (* Of for *)ππ          Case UseNew ofπ         (* >= DOS 4.0 and NOT OS2 *)π            true  : beginπ                      MDA := CurrDpb^.MdaNew;π                      SPF := CurrDpb^.SpfNew;π                    end;π          (* < DOS 4 or OS2 *)π            false : beginπ                      MDA := CurrDpb^.MdaOld;π                      SPF := CurrDpb^.SpfOld;π                    end;π            end;   (* Of case *)ππ       (* Write out buncha stuff for analysis *)π          writeln(f,'DN   is : ',CurrDpb^.DN);π          writeln(f,'DDU  is : ',CurrDpb^.DDU);π          writeln(f,'BPS  is : ',CurrDpb^.BPS);π          writeln(f,'SPC  is : ',CurrDpb^.SPC);π          writeln(f,'CSC  is : ',CurrDpb^.CSC);π          writeln(f,'BS   is : ',CurrDpb^.BS);π          writeln(f,'FATS is : ',CurrDpb^.Fats);π          writeln(f,'RDE  is : ',CurrDpb^.RDE);π          writeln(f,'FDS  is : ',CurrDpb^.FDS);π          writeln(f,'HPC  is : ',CurrDpb^.HPC);π          writeln(f,'SPF  is : ',SPF);π          writeln(f,'MDA  is : ',MDA);ππ    (* This work on last of multiple Benoulli drives ???? *)π          if (SPF > 2) AND (MDA >= $fc) thenπ                  DriveType := Bernoulliπ          elseπ          if num = 0 thenπ            beginπ    (* Tell DOS to build new BPB for removable types *)π              fillchar(params,sizeof(params),0);π              params[0] := 4;   (* Do NOT go to drive ! *)π              ax := $440d;π              cx := $0860;π              bl := dnum;π              dx := ofs(params);π              ds := seg(params);π              Intr($21, regs);π              Case params[1] ofπ                0  : DriveType := Floppy360;π                1  : DriveType := Floppy12;π                2  : DriveType := Floppy720;π               3,4 : DriveType := Floppy;π                6  : DriveType := TapeDrive;π                7  : DriveType := Floppy14;π                8  : DriveType := Floptical;π                9  : DriveType := Floppy28;π                end;π                  beginπ                    writeln(f,'Params[1] is : ',byte(params[1]));π                    writeln(f,'BPS  is : ',word(params[7]));π                    writeln(f,'SPC  is : ',byte(params[9]));π                    writeln(f,'Fats is : ',byte(params[12]));π                    writeln(f,'RDE  is : ',word(params[13]));π                    writeln(f,'SPF  is : ',word(params[18]));π                    writeln(f,'MDA  is : ',byte(params[17]));π                  end;π            end     (* Of Not Bernoulli *)π      { end}π      else    (* ax > 0 ! *)π        beginπ          Case num ofπ            1 : DriveType := HardDrive;π            5 : DriveType := BootHrdDrive;π            6 : beginπ                  if IsCdRom(drive) thenπ                     DriveType := CDRomπ                   else DriveType := RamDrive;π                end;π            else DriveType := 0;            (* Error ! *)π            end;  (* Of case *)π        end;  (* Not a floppy or bernoulli *)π    end;   (* With regs *)πEnd;πππππBegin      (* TestDisk *)π  GetDate(y,m,d,dow);π  {$I-}π  assign(f,'TESTDISK.RPT');π  rewrite(f);π  if IoResult <> 0 thenπ    beginπ      write(^G);π      writeln('Can''t open report file: aborting !');π      exit;π    end;π  SetTextBuf(f,buff);π  writeln(f);π  writeln(f,'DOS Drive Detection Survey Report');π  writeln(f);π  writeln(f,'Please mail to: CDC Micro');π  writeln(f,'                PO Box 4457');π  writeln(f,'                Seattle WA 98104');π  writeln(f,'                (206) 435-1125');π  writeln(f);π  writeln(f,'Thanks for taking the time to help with this survey !');π  writeln(f);π  writeln(f,'Report dated : ',m:0,'/',d:0,'/',y:0);π  writeln(f);π  writeln(f,'Report submitted by : _________________________________________________________');π  writeln(f,'My address & phone # is : _____________________________________________________');π  writeln(f,'_______________________________________________________________________________');π  writeln(f,'Test equipment is : ___________________________________________________________');π  writeln(f,'_______________________________________________________________________________');π  writeln(f,'For this test, my machine was booted from the: _______ drive.');π  writeln(f,'For this test, I was running a RamDisk on Drive: ______,using _________________');π  writeln(f,'For this test, I had a Bernoulli drive connected as Drive: ________ (Yes/No?)');π  writeln(f,'For this test, I had a Tape/Optical drive connected as Drive: _______ (Yes/No?)');π  writeln(f,'For this test, I was running Stacker/DoubleSpace/Other compressor. (Yes/No ?)');π  writeln(f,'Test Conducted under : __________________________ operating/system/environment');π  writeln(f,'Comments ? ____________________________________________________________________');π  writeln(f);π  version := DosVersion;π  writeln(f,'DOS Version: ',version);π  if (version < 310) OR (NOT GetLastDrive(lastdrive)) thenπ  writeln(f,'Dos Version too low or lastdrive detection FAILED !!')π  else beginπ  writeln(f,'LastDrive is: ',lastdrive:0);π  writeln(f);π  for i := 1 to lastdrive do with regs doπ    beginπ      drive := char(i+64);π       if DriveValid(drive) thenπ         beginπ          IsHardDisk(drive);π          Dtype := ax+(flags AND fCarry)+(flags AND fParity);π          bits := BinStr(flags,16);π          writeln(f,'Drive '+Drive+':          Value of AX is: ',ax);π          writeln('Drive '+Drive+':          Value of AX is: ',ax);π          writeln(f,'Drive '+Drive+':       Value of flags is: ',flags);π          writeln('Drive '+Drive+':       Value of flags is: ',flags);π          writeln(f,'Drive '+Drive+':          Flags bits are: '+bits);π          writeln('Drive '+Drive+':          Flags bits are: '+bits);π          writeln(f,'Drive '+Drive+':      AX+carry+parity is: ',ax+(flags AND fCarry)+(flags AND fParity));π          writeln('Drive '+Drive+':      AX+carry+parity is: ',Dtype);ππ          writeln(f,'Drive '+Drive+':     flags AND fCarry is: ',flags AND fCarry,' ',flags AND fCarry = fCarry);π          writeln('Drive '+Drive+':     flags AND fCarry is: ',flags AND fCarry,' ',flags AND fCarry = fCarry);π          writeln(f,'Drive '+Drive+':    flags AND fParity is: ',flags AND fParity,' ',flags AND fParity = fParity);π          writeln('Drive '+Drive+':    flags AND fParity is: ',flags AND fParity,' ',flags AND fParity = fParity);π          writeln(f,'Drive '+Drive+': flags AND fAuxiliary is: ',flags AND fAuxiliary,' ',flags AND fAuxiliary = fAuxiliary);π          writeln('Drive '+Drive+': flags AND fAuxiliary is: ',flags AND fAuxiliary,' ',flags AND fAuxiliary = fAuxiliary);π          writeln(f,'Drive '+Drive+':      flags AND fZero is: ',flags AND fZero,' ',flags AND fZero = fZero);π          writeln('Drive '+Drive+':      flags AND fZero is: ',flags AND fZero,' ',flags AND fZero = fZero);π          writeln(f,'Drive '+Drive+':      flags AND fSign is: ',flags AND fSign,' ',flags AND fSign = fSign);π          writeln('Drive '+Drive+':      flags AND fSign is: ',flags AND fSign,' ',flags AND fSign = fSign);π          writeln(f,'Drive '+Drive+':  flags AND fOverFlow is: ',flags AND fOverflow,' ',flags AND fOverFlow = fOverFlow);π          writeln('Drive '+Drive+':  flags AND fOverFlow is: ',flags AND fOverflow,' ',flags AND fOverFlow = fOverFlow);ππ          if (Dtype > 0) then if DriveIsRemote(Drive)π                then writeln(f,'  ***** This drive is remote (network) or Substituted ?  Yes/No/Which  *****');ππ          writeln(f,'       *****  This is a '+DriveTypes[DriveType(f,Drive)]+' ?  Yes/No  *****');π          writeln(f);π          writeln;π        end;    (* Drive is valid *)π    end;     (* For loop *)π  end;   (* Lastdrive detection *)π  writeln(f,'End of Report... and Thanks for running this test !');π  close(f); {$I+}π  if IoResult <> 0 then;ππ  writeln('Please print out and mail in the TESTDISK.RPT file.');π  writeln('You''ll find it in this sub-directory.');π  writeln('Thanks for running this test !');πEnd.